Histoire de cadre : élaboration d’une trajectoire spatio-temporelle
Exemple appliqué d’un notebook avec R sur des données Wikidata
L’objectif de ce document computationnel (notebook R ou R Markdown) est de partager une analyse exploratoire de données1, suffisamment détaillée pour être intelligible pour un large public et reproductible à l’identique sur sa machine.
Le notebook permet ainsi de présenter clairement, étape par étape, toute une chaîne de traitements de données réalisée avec R à un public qui ne maîtrise pas forcément ce langage.
Un certain nombre de métadonnées2 associées au notebook (information de session, liste et version de packages, bibliographie, glossaire, difficultés rencontrées…) fournit les informations nécessaires à la réutilisation d’une partie du code par les lecteurs et lectrices, voire de reproduire ce document et l’exécuter en local sur son propre ordinateur.
Introduction
Nous présentons dans ce document une chaîne complète de traitements de données Wikidata, de leur collecte à leur visualisation graphique. Le processus exploratoire des données, parfois itératif, a été conservé. Cela permet de bien comprendre l’approche réflexive des auteurs et autrices et de retranscrire au mieux la démarche scientifique exploratoire.
Dans ce notebook, les données utilisées sont celles disponibles et mises en jour sur Wikidata. Elles sont structurées sous une forme décrite sommairement ci-dessous (voir Fig. 1). Pour plus d’informations, il est possible de consulter l’introduction à Wikidata ou la page Wikibase dédiée au formalisme du Ressource Description Framework (RDF) du dépôt de données Wikidata.
Fig.1 Diagramme d’une entité Wikidata avec les principaux termes utilisés (Source : Wikidata)
Les principaux termes utilisés figurent dans le glossaire du notebook (et pour aller plus loin, le glossaire de Wikidata).
L’idée de départ qui conduit à la démarche proposée, est d’accéder à
un dépôt de données de sorte à interroger une ou des modalités possibles
pour tracer une ou des trajectoires3. Compte-tenu du
formalisme et de la spécificité des données non supervisées de Wikidata,
l’objet choisi pour l’étude est une peinture sur son support physique
inséré dans un cadre, susceptible d’être exposée au sein d’un musée ou
d’une institution culturelle dans le monde. (voir les données utilisées).
1 R, code source et packages
Ce document computationnel (Notebook) peut être reproduit à l’identique sur un ordinateur. Pour cela il est nécessaire d’avoir installé l’environnement logiciel R .
1.1 Installer R et RStudio
Seul l’environnement logiciel R est indispensable pour
reproduire ce document. Mais il est fortement conseillé d’installer
également l’environnement de développement intégré (IDE4) RStudio qui
facilite considérablement la pratique de R et la production de
documents au format R Markdown.
R et RStudio s’installent comme n’importe quel autre
logiciel :
- Télécharger
R, mis à disposition sur le Comprehensive R Archive
Network (CRAN) ;
- Télécharger RStudio (RStudio Desktop
Free version) sur le site de l’entreprise.
1.2 Packages associés au
Notebook, knitr & rmdformats
Deux packages5 sont nécessaires pour reproduire ce
document à l’identique :
- knitr : offre des outils pour la génération de rapports
dynamiques (literate programming) ;
- rmdformats : met à disposition le modèle
(template) de mise en page HTML utilisé (adapté de
readthedown6).
Installer ces packages, en exécutant la ligne de commande suivante dans la console R :
install.packages("knitr", "rmdformats")En fonction du système d’exploitation utilisé, il peut-être nécessaire d’installer des logiciels ou des bibliothèques logicielles dont certains packages dépendent.
Sur Windows, l’exécution d’un fichier au format R
Markdown (avec knitr) nécessite l’installation du
logiciel Pandoc7.
1.3 Code source du document
Pour les utilisateurs et utilisatrices du logiciel de gestion de versions Git, le dépôt du code source est accessible ici :
Sinon, il est possible de télécharger le code source de ce document R Markdown en cliquant sur le lien ci-dessous.
Décompresser le dossier, puis double-cliquer sur le fichier
projet Rmarkdown.Rproj pour ouvrir le projet dans l’IDE
RStudio.
1.4 Packages nécessaires au traitement des données et à la représentation d’une trajectoire
Les packages utilisés pour le processus d’exploration de données présenté dans ce document sont :
WikidataQueryServiceR: fournit une interface de programmation (API client) pour le Wikidata Query Service ;
rnaturalearth: met à disposition les données cartographiques de Natural Earth ;
sf: permet la gestion et la manipulation (géotraitement) de données géographiques ;
mapview: permet de produire facilement des cartes interactives (leaflet) ;
tmap: permet de produire de cartes thématiques ;ggplot2: permet de produire des graphiques, basés sur la grammaire graphique théorisée par Leland Wilkinson ;
patchwork: permet de combiner facilement plusieurs graphiquesggplot2;
jpeg: permet d’importer, enregistrer et afficher des images matricielles (format bitmap) ;DT: fournit une mise en forme dynamique (HTML) de tableaux de données (bibliothèque javascript DataTables).
Ces packages seront automatiquement installés en exécutant (knitant) le fichier source (mon_notebook_final.rmd).
# Packages nécessaires
mes_packages <- c("WikidataQueryServiceR",
"rnaturalearth",
"sf",
"mapview",
"tmap",
"ggplot2",
"patchwork",
"jpeg",
"DT")
# Packages qui n'ont pas été encore installés
mes_packages_no_install <- mes_packages[!(mes_packages %in% installed.packages()[,"Package"])]
# Installation des packages manquants
install.packages(mes_packages_no_install)Sur Linux, il est parfois nécessaire d’installer GDAL
(bibliothèque permettant de lire et de traiter un très grand nombre de
formats de données spatiales) pour utiliser le package
sf.
L’ensemble des informations du système et des versions de packages utilisés est fournit en fin de document.
2 Données utilisées
2.1 Wikimédia & Wikiproject
Wikimédia fournit l’infrastructure nécessaire à la connaissance libre (source : Wikimedia). Les projets de la fondation sont déclinés en catégories, par exemple, les ouvrages de références comme Wikipédia ou Wiktionnaire, les médiathèques comme Wikimédia Commons, ou encore des guides ou technologies, comme Wikidata.
Les contributeurs et contributrices au projet global Wikidata sont organisées en projets thématiques qui se ramifient en sous groupes (par exemple, le groupe qui s’intéresse aux peintures).
Dans le cas de ce notebook, on s’intéresse aux arts visuels et notamment une partie des données qui ont permis de construire le portail Wikiart.
2.2 Données Wikidata
Wikidata est une base de connaissances libre éditée de manière
collaborative et hébergée par la Wikimedia Foundation. Son contenu étant
placé sous licence CC0, elle permet de centraliser les données
utilisées par différents projets Wikimedia (source : Wikipédia).
Les informations saisies dans Wikidata sont des données “brutes”
multilingues non-supervisées (voir Fig.2).
Fig.2 Données Wikipédia (DBpédia) vs données Wikidata (source : Wikidata-Basics/Wikidata Hackathon event for the Festival of Creative Learning 2018)
2.3 Stratégie exploratoire & standard RDF du World Wide Web Consortium (W3C)
La première étape est de configurer le notebook pour permettre l’interrogation de données à distance au sein d’un dépôt de données accessibles dans un cadre de description standard du web sémantique. Ces données sont accessibles sous une forme générique de graphes de données associés aux objets (voir la Fig.3).
Fig.3 Exemple de graphe de triplets (source : W3C)
Une unité de construction d’un graphe de données est un
triplet du cadre de description des ressources du W3C (RDF). Il adopte
une forme générale sujet - prédicat - objet.
Par exemple, l’assertion ou déclaration “Bob est intéressé par Mona
Lisa” est formalisée selon une représentation dans la Fig. 4.
Fig.4 Composantes génériques d’un triplet RDF
2.4 Description des données et du modèle de données
La description ci-dessous n’est pas exhaustive. Pour de plus amples informations, se référer à la documentation de Wikidata.
Dans ce notebook, les peintures sont des objets décrits par leurs
relations aux données instanciant certaines classes et propriétés de
Wikidata utiles à l’étude de cas proposée.
Les peintres, peintures et lieux d’exposition sont modélisés selon la
représentation schématique ci-dessous, comprenant des entités liées
entre elles et mobilisant une syntaxe spécifique avec des
préfixes8.
Afin de disposer des données relatives à une œuvre visuelle, son auteur ou autrice et sa localisation, plusieurs données associées à l’artiste, à l’œuvre (voir Fig. 5) ou aux déclarations sur celle-ci (statements, voir Fig.6) sont nécessaires, notamment :
l’auteur ou l’autrice (ici le peintre) est une entité (préfixe
wd) ayant pour propriété directe (préfixewdt) :la désignation de l’œuvre elle-même, par le biais de l’entité (préfixe
wd) associée à l’identifiant qui la représente, par exemplewd:Q4660880pour l’œuvre dénommée A Young Woman Seated at the Virginals du peintre Johannes Vermeer.la localisation de l’entité au moyen de la propriété (P276), permettant l’accès aux assertions ou déclarations
de localisation actuelle ou de dernière localisation renseignée (selon les données non supervisées) de l’œuvre dans un lieu (géographique & institutionnel) :
wdt:P276ou d’un volume spatio-temporel (couplant lieu et laps de temps) :
p:P276associée aux qualifiers de la déclaration de lieu (préfixepq) donnant le laps de temps associé, le cas échéant (P580 et P582) ;
les coordonnées de la localisation associée à l’œuvre au moyen de la propriété directe (P625) :
wdt:P625.
Fig.5 Classes et propriétés générales de Wikidata mobilisées dans l’étude de cas proposée
Fig.6 Classes et propriétés spécifiques de Wikidata mobilisées dans le cas d’une déclaration (statement)
3 Interroger Wikidata
Un service de
collecte des données de Wikidata en langage SPARQL est disponible et
offre une solution très complète en première approche (exemples,
assistant de requêtes, diversité des représentations etc.). Toutefois,
pour explorer la question de la représentation d’une
trajectoire d’une peinture, la solution du notebook R
offre une alternative concrète à une complexité intrinsèque au langage
SPARQL.
Le package WikidataQueryServiceR fournit une interface de
programmation d’application (API) pour interroger le Wikidata Query
Service directement via R.
La première étape est de permettre à l’utilisateur ou utilisatrice du notebook d’identifier l’artiste qu’il ou elle va choisir. On choisit arbitrairement, dans cette étude de cas, les œuvres de Johannes Vermeer. Toutefois, il sera possible de jouer, en fin d’exercice, pour obtenir les données d’œuvres d’autres peintres ou artistes.
3.1 Première requête SPARQL
La requête ci-dessous demande l’identifiant d’une entité ayant pour propriété (P31) d’appartenir à la classe des êtres humains (Q5) qui entre dans la catégorie Commons (P373) Johannes Vermeer et dont on demande une image (P18).
# Package API pour le 'wiki data service'
library(WikidataQueryServiceR)
# Requête SPARQL
# Recherche de l'artiste nommé 'Johannes Vermeer' et d'une illustration associée
data1 <- query_wikidata('
SELECT ?identifiant ?image WHERE {
SERVICE wikibase:label { bd:serviceParam wikibase:language "[AUTO_LANGUAGE],en". }
?identifiant wdt:P31 wd:Q5 ; wdt:P373 "Johannes Vermeer" .
?identifiant wdt:P18 ?image .
}
')Affichage des données collectées
# Affichage dynamique de la table
library(DT)
datatable(data1)Deux URL sont collectées
- data1\(identifiant](http://www.wikidata.org/entity/Q41264){target="_blank"}
: le lien vers la page wikidata du peintre Johannes Vermeer ; -
[data1\)image : le lien vers l’image associée à ce peintre
dans wikidata.
Sauvegarde de l’image de l’artiste
# Création des sous-répertoires 'data' et 'data/image'
dir.create("data")
dir.create("data/images")# Téléchargement et sauvegarde de l'image sur sa machine
download.file(url = data1$image,
destfile = 'data/images/portrait_artiste.jpg',
mode = 'wb')Fig.7 Image wikidata pour le peintre Johannes Vermeer (ID = Q41264)
3.2 Seconde requête SPARQL
En second lieu, on propose de lister l’ensemble des œuvres de l’artiste choisi (dont l’identifiant ici est (Q41264) pour Johannes Vermeer).
La requête ci-dessous demande l’identifiant d’une entité - une œuvre, ayant pour créateur (P170) l’artiste choisi (Q41264) ; chaque œuvre ayant la propriété d’être exposée dans un lieu donné (P276), associé à une localisation géographique9 (P625).
# Requête SPARQL
# Recherche de toutes les œuvres de Johannes Vermeer et de leurs localisations (musée)
data2 <- query_wikidata('
SELECT ?oeuvreLabel ?museeLabel ?coord
WHERE { SERVICE wikibase:label { bd:serviceParam wikibase:language "[AUTO_LANGUAGE],en". }
?oeuvre wdt:P170 wd:Q41264 .
OPTIONAL {?oeuvre p:P276 ?loc . ?loc ps:P276 ?musee . ?musee wdt:P625 ?coord} .
}
')Affichage des données collectées
# Affichage de la table
datatable(data2)On constate que les données non supervisées de localisation atcuelle ou de dernière localisation des oeuvres sont hétérogènes : certaines œuvres ont plusieurs localisations (par exemple Girl with a Pearl Earring ou View of Delft dans la page 2 du tableau), d’autres n’en n’ont aucune (par exemple The Concert ou The Lacemaker).
Pourquoi ?
En explorant les données collectées, plusieurs localisations semblent possibles :
soit une même œuvre est localisée dans plusieurs musées ;
soit un même musée possède des coordonnées géographiques différentes.
Ce constat nécessite d’entrer plus en détail dans les déclarations (statements) renseignées pour la donnée Wikidata, notamment la localisation de l’œuvre au cours du temps entre divers musées ou institutions culturelles de divers pays, en utilisant les valeurs et qualificatifs (qualifiers) associés aux propriétés figurant dans les déclarations (voir Figure 1.).
Par exemple, l’œuvre de Johannes Vermeer intitulée A Young Woman
Seated at the Virginals (entité Wikidata Q4660880) semble être l’œuvre de Johannes Vermeer
qui a le plus voyagé. Cela signifie que cette entité possède le
plus grand nombre de valeurs associées à la propriété location
(propriété Wikidata P625) dans les déclarations ou statements de
localisation désignant des lieux (préfixe ps), dont les
coordonnées sont données par la propriété Wikidata (P276).
3.3 Troisième requête SPARQL
Pour connaître les modalités de circulation de l’œuvre dans divers musées et institutions, la requête ci-dessous collecte les différents lieux d’exposition (P276), leurs noms ainsi que le volume spatio-temporel composé de l’association des coordonnées géographiques (P625) et des dates de début et de fin (P580 & P582) de la période pendant laquelle l’œuvre (A Young Woman Seated at the Virginals) semble être présente dans le lieu, voir notamment la figure 5 ci-dessus.
# Requête SPARQL
# Recherche de toutes les localisations + dates associées à
# l'œuvre "A Young Woman Seated at the Virginals" de Johannes Vermeer
data <- query_wikidata('
SELECT ?image ?nomLabel ?dated ?datef ?coord WHERE {
SERVICE wikibase:label { bd:serviceParam wikibase:language "[AUTO_LANGUAGE],en". }
wd:Q4660880 p:P276 ?location ; wdt:P18 ?image .
?location ps:P276 ?nom .
?location pq:P580 ?dated .
?location pq:P582 ?datef .
?nom wdt:P625 ?coord .
}
')Affichage des données collectées
# Affichage de la table
datatable(data)Enregistrement et (ré)import des données
# Enregistrement des données en local
write.csv(x = data, file = "data/data.csv", row.names = FALSE)
# Import du fichier de données enregistré
data <- read.csv("data/data.csv", row.names = NULL)Enregistrement de l’image de l’œuvre sur sa machine
# Téléchargement et sauvegarde en local de l'image
download.file(url = data$image[1],
destfile = 'data/images/Q4660880.jpg',
mode = 'wb')Fig.8 ‘A Young Woman Seated at the Virginals’ de Johannes Vermeer (1670)
Les trois requêtes SPARQL ont permis de collecter respectivement :
- l’identifiant et l’image associés à Johannes Vermeer dans wikidata
(‘data1’) ;
- les œuvres du peintre Johannes Vermeer et leur localisation (musée +
coordonnées) (‘data2’) ;
- l’ensemble des informations géographiques de localisation (nom du musée + coordonnées spatio-temporelles) de l’œuvre A Young Woman Seated at the Virginals de Johannes Vermeer (‘data’).
4 Pré-traitement des données collectées
Les données non-supervisées collectées nécessitent d’être contrôlées et nettoyées avant d’être exploitées.
4.1 Localisation des oeuvres de Johannes Vermeer
Pour rappel, les données issues de la seconde requête SPARQL (‘data2’) listent l’ensemble des œuvres de Vermeer et leurs localisations respectives (nom du musée + coordonnées géographiques) quand elles existent selon Wikidata.
4.1.1 Nettoyage des données collectées
Comme vu précédemment (cf. partie 3.2), il peut y avoir aucune ou plus d’une donnée de localisation associée aux œuvres.
Après vérification, pour chaque œuvre présentant plusieurs coordonnées, la dernière localisation qui apparaît dans le tableau de données collectées est également la dernière localisation renseignée dans les assertions ou déclarations de Wikidata de l’œuvre concernée.
Suppression des doublons en ne gardant que le premier item qui apparaît dans la table de données collectées
# Détection/Suppression doublon(s)
data2 <- data2[!duplicated(data2$oeuvreLabel), ]L’exploration s’arrête à cette étape pour les œuvres dont les données de localisation Wikidata sont absentes.
Suppression de toutes les œuvres pour lesquelles aucune localisation n’est renseignée.
# Suppression NA
data2 <- data2[!is.na(data2$coord), ]Affichage des données nettoyées
datatable(data2)4.1.2 Regroupement par musée
Les localisations collectées sont celles des musées qui exposent les œuvres choisies pendant une durée donnée. Plusieurs œuvres présentent plusieurs fois la même localisation dans Wikidata.
Certaines œuvres semblent exposées (localisation actuelle ou dernière localisation) dans les mêmes musées (même nom et mêmes coordonnées). Ce constat nécessite, pour la poursuite de l’exploration, un regroupement des œuvres par intitulé des musées - la valeur de ‘museeLabel’, en calculant le nombre d’œuvres de Vermeer que chacune de ces institutions expose.
Affichage du regroupement des données de localisation de chaque œuvre
# Regroupement - Calcul du nombre œuvres par musée
nb_oeuvre_by_musee <- aggregate(oeuvreLabel ~ coord + museeLabel, data = data2, FUN = length)
# Affichage du résultat
datatable(nb_oeuvre_by_musee)4.1.3 Géoréférencement
A partir de la variable ‘coord’, il est simple de transformer ce tableau de données en couche géographique, où les individus/entités (musées) sont précisément localisés dans l’espace, cela en deux étapes :
Création des colonnes ‘long’ et ‘lat’ à partir de la colonne ‘coord’
# Suppression des chaînes de caractères "Point(" et ")"
nb_oeuvre_by_musee$coord <- gsub(pattern = 'Point\\(', replacement = '', nb_oeuvre_by_musee$coord)
nb_oeuvre_by_musee$coord <- gsub(pattern = '\\)', replacement = '', nb_oeuvre_by_musee$coord)
# Séparation longitude et latitude en deux colonnes
out <- strsplit(nb_oeuvre_by_musee$coord, split = ' ')
musee_geo <- cbind(nb_oeuvre_by_musee, do.call(rbind, out))
# Renommage de colonnes créées
colnames(musee_geo)[4:5] <- c('long', 'lat')La table de données comporte dorénavant deux nouvelles colonnes (‘long’ et ‘lat’).
Conversion du tableau en couche géographique, à partir des variables ‘long’ et ‘lat’
# Bibliothèque pour la gestion de données géographiques
library(sf)
# Géoréférencement (tableau de données -> couche géographique)
musee_geo <- st_as_sf(musee_geo, coords = c("long", "lat"), crs = 4326)Affichage de la couche géographique créée
Il est très facile d’afficher les points crées (musées) sur une carte
interactive, en utilisant la bibliothèque mapview. Cela
permet, entre autre, de vérifier la qualité des données et du
géoréférencement effectué.
# Bibliothèque pour la cartographie interactive
library(mapview)
# Affichage de la couche géographique des musées
mapview(musee_geo)4.2 Trajectoire de l’œuvre intitulée ‘Dame assise au virginal’
Pour rappel, les données issues de la troisième requête SPARQL (‘data’) listent l’ensemble des localisations de l’œuvre de Johannes Vermeer A Young Woman Seated at the Virginals (ou Dame assise au virginal en français) au cours du temps.
4.2.1 Nettoyage des données
Dans le tableau de données collectées (cf. partie 3.3), deux paires de coordonnées sont renseignées pour un même musée, le musée italien Scuderie del Quirinale. On constate que ces coordonnées géographiques différent très légèrement (de quelques mètres…). Or, par définition, une œuvre ne peut pas être à deux endroits différents en même temps !
Suppression des doublons en utilisant la date d’arrivée dans les musées
# Détection/Suppression doublon(s)
data <- data[!duplicated(data$dated), ]
# Une ligne a été supprimée
nrow(data)[1] 19
4.2.2 Géoréférencement
Comme pour le tableau de données précédant (‘data2’), nous géoréférençons les musées concernées à partir de la variable ‘coord’ afin de créer une couche géographique, en deux étapes.
Affichage des coordonnées géographiques collectées
data$coord [1] "Point(37.605 55.747222222)" "Point(2.335833333 48.861111111)"
[3] "Point(30.313611111 59.940555555)" "Point(-73.963333333 40.779444444)"
[5] "Point(-73.963333333 40.779444444)" "Point(-0.128299 51.508929)"
[7] "Point(-75.181284 39.965827)" "Point(-75.181284 39.965827)"
[9] "Point(-1.26056 51.75556)" "Point(-1.26056 51.75556)"
[11] "Point(-96.800830555 32.787219444)" "Point(139.773 35.7172)"
[13] "Point(-86.8102 33.5219)" "Point(116.394444 39.903333)"
[15] "Point(0.119444 52.200278)" "Point(-78.70288889 35.81019444)"
[17] "Point(-76.2924 36.857)" "Point(121.464313 31.183945)"
[19] "Point(12.48603 41.8987)"
Création des colonnes ‘long’ et ‘lat’ à partir de la colonne ‘coord’
# Suppression des chaînes de caractères "Point(" et ")"
data$coord <- gsub(pattern = 'Point\\(', replacement = '', data$coord)
data$coord <- gsub(pattern = '\\)', replacement = '', data$coord)
# Séparation longitude et latitude en deux colonnes
out <- strsplit(data$coord, split = ' ')
data_geo <- cbind(data[-5], do.call(rbind, out))
# Renommage de colonnes créées
colnames(data_geo)[5:6] <- c('long', 'lat')Conversion du tableau en couche géographique, à partir des variables ‘long’ et ‘lat’
# Géoréférencement des musées
data_geo <- st_as_sf(data_geo, coords = c("long", "lat"), crs = 4326)
# Affichage de la couche géographique des musées
mapview(data_geo)
Les données semblent correctement géoréférencées.
L’exploration spatiale des données ainsi nettoyées peut
démarrer !
5 Exploration d’une trajectoire spatiale
5.1 Les œuvres de Johannes Vermeer
5.1.1 Cartographie thématique
À partir des données collectées et pré-traitées, il est possible de réaliser une carte utilisant des symboles de proportionnalité qui permettent de représenter le nombre d’œuvres localisées par musée.
Réalisation d’une carte thématique : pondération du nombre d’œuvres par musée
# Bibliothèque pour la cartographie thématique
library(tmap)
# Mode cartographie interactive
tmap_mode(mode = "view")
# Carte thématique
tm_basemap() +
tm_shape(musee_geo) +
tm_symbols(size="oeuvreLabel",
scale = 4,
col="red3",
border.col="white",
alpha =0.5,
border.lwd=0.1,
border.alpha=0.5,
title.size = "Nb d'œuvres",
id = "museeLabel",
popup.vars=c("Nombre d'œuvres"="oeuvreLabel"))5.1.2 Enrichissement des données collectées : jointure avec les pays
Au vue de la carte précédente, il semble intéressant de représenter
la répartition des œuvres de Johannes Vermeer par pays. Pour cela, il
est nécessaire d’enrichir les données en ajoutant pour chaque musée, le
pays où il se situe.
Plusieurs étapes sont alors nécessaires.
Téléchargement d’un fond de carte pays
# Bibliothèque qui permet d'accéder aux données Natural Earth
library(rnaturalearth)
# Téléchargement d'un fond de carte pays
world <- ne_download(scale = "small",
type = "countries",
category = "cultural",
destdir = "data/world",
load = TRUE,
returnclass = "sf")# Affichage du fond de carte collecté
plot(st_geometry(world))Modification de la projection cartographique utilisée (de WGS84 vers Robinson)
# Reprojection du fond de carte pays (polygones)
world <- st_transform(x = world, crs = "+proj=moll", use_gdal = FALSE)
# Reprojection de la couche géographique (points)
musee_geo <- st_transform(musee_geo, crs = st_crs(world))# Affichage du fond de carte collecté selon la projection Robinson
plot(st_geometry(world))La jointure spatiale permet de collecter, pour
chaque point (les coordonnées collectées pour chaque musée), le pays
dans lequel il se situe.
Pour cela, on utilise la fonction st_intersection du
package sf.
Jointure spatiale des coordoonnées des musées et des pays
# Jointure spatiale
# Collecte du code ISO3 de tous les pays (uniquement)
musee_geo <-st_intersection(musee_geo, world[,"ADM0_A3"])Collecte du code ISO3 du pays pour chaque point (musée)
5.1.3 Représentation de la répartition des œuvres par pays
Pour représenter la répartition en nombre des œuvres de Johannes Vermeer dans chaque pays, deux étapes sont nécessaires :
- le calcul le nombre d’œuvres par pays ;
- la réalisation de la carte.
Calcul du nombre d’œuvres par pays
# Regroupement - Calcul du nombre œuvres par pays
nb_oeuvre_musee_geo <- aggregate(oeuvreLabel ~ ADM0_A3, data = musee_geo, FUN = sum)Représentation graphique
Nous pouvons alors construire un graphique représentant le nombre
d’œuvres par pays.
# Bibliothèque de représentation graphique
library(ggplot2)
# Graphique en barre - Nombre d'œuvres par pays
ggplot(data = nb_oeuvre_musee_geo, aes(x = ADM0_A3, y = oeuvreLabel, fill=ADM0_A3) ) +
geom_bar(stat="identity") +
ggtitle("Nombre d'œuvres de Johannes Vermeer par pays") +
xlab("") +
ylab("") +
scale_fill_brewer(palette="Set1") +
theme(legend.position = "none")5.2 Trajectoire spatiale de la peinture ‘Dame assise au virginal’
5.2.1 Cartographie exploratoire
Réalisation d’une carte interactive exploratoire : amélioration de la mise en page et affichage de variables dans des fenêtres pop-up
# Popup content
content <- paste0( "<img src='http://commons.wikimedia.org/wiki/Special:FilePath/Vermeer%20-%20A%20young%20Woman%20seated%20at%20the%20Virginals.jpg' width='180'><br /><b>", data_geo$nomLabel,
"</b><br />Du ",data_geo$dated,
"<br />Au ", data_geo$datef)
# Carte
mapview(data_geo,
zcol = "nomLabel",
col.regions = "red",
legend = FALSE,
popup = content,
map.types = "Esri.WorldImagery")5.2.2 Enrichissement de la représentation d’une trajectoire spatiale de l’œuvre
Comme effectué précédemment, pour les musées hébergeant l’ensemble de œuvres de Johannes Vermeer, il est possible de tracer, dans un premier temps, une trajectoire spatiale du tableau A Young Woman Seated at the Virginals en comptabilisant le nombre d’expositions effectuées par pays.
Les données spatiales collectées sont enrichies de la même façon que
celle présentée dans la partie 5.1.2. Pour
identifier les pays qui ont abrités l’œuvre au cours du temps, on
réalise une jointure spatiale en utilisant la fonction
st_intersection du package sf.
Modification de la projection cartographique utilisée (WGS84 vers Robinson)
# Reprojection de la couche géographique (points)
data_geo <- st_transform(data_geo, crs = st_crs(world))Jointure spatiale points/pays
# Jointure spatiale
data_geo <-st_intersection(data_geo, world[,"ADM0_A3"])On vérifie que le code ISO3 du pays a bien été collecté pour chaque point (musée).
5.2.3 Répartition spatiale des expositions de l’œuvre par pays
# Package de représentation graphique
library(ggplot2)
# Graphique en barre - Nombre d'expositions de l'œuvre par pays
ggplot(data = data_geo, aes(factor(ADM0_A3), fill=factor(ADM0_A3)) ) +
geom_bar() +
ggtitle("Nombre d'exposition de l'œuvre par pays") +
xlab("") +
ylab("") +
scale_fill_brewer(palette="Set1") +
theme(legend.position = "none")
Graphique 2 : Représentation histographique du nombre d’expositions
de l’œuvre de Johannes Vermeer dans chaque pays, selon Wikidata
6 Exploration d’une trajectoire spatio-temporelle
Après avoir exploité la dimension spatiale des données collectées, la suite du document procède à l’exploration de la dimension temporelle des données associées au tableau A Young Woman Seated at the Virginals : les dates ou durées d’exposition de l’œuvre dans les différents musées localisés et identifiés dans Wikidata.
Il semble que la meilleure représentation de ces données spatio-temporelles ne soit pas forcément une carte. En effet, la construction d’un graphique s’apparentant à une frise chronologique paraît plus efficace. Pour cela, une série de pré-traitement des données est nécessaire.
6.1 Préparation des données spatio-temporelles collectées
En cohérence avec les constats et conclusions précédentes, les traitements successifs permettent de procéder :
- au formatage des dates collectées ;
- au nettoyage des données ;
- à l’affichage des données spatio-temporelles.
Modification du format de stockage des dates (string to date) dans le tableau ‘data_geo’
# Format date
data_geo$datef <- as.Date(data_geo$datef)
data_geo$dated <- as.Date(data_geo$dated)Tri du tableau en fonction de la date (‘dated’) d’arrivée dans chaque musée.
data_geo <- data_geo[order(data_geo$dated, decreasing = FALSE),]Ajout d’un ID pour chaque ligne du tableau
data_geo$ID <- 1:nrow(data_geo)Tri d’ordre d’apparition des modalités pour les variables ‘nomLabel’ et ‘ADM0_A3’
# liste unique musée
musee <- unique(data_geo$nomLabel)
data_geo$nomLabel <- ordered(as.factor(data_geo$nomLabel), levels = musee)
# liste unique pays
countries <- unique(data_geo$ADM0_A3)
data_geo$ADM0_A3 <- ordered(as.factor(data_geo$ADM0_A3), levels = countries)Création d’une nouvelle colonne avec les noms des musées qui n’apparaissent qu’une fois
# Label unique pour les pays
museum_label <- data_geo[!duplicated(data_geo$nomLabel),]
data_geo <- merge(data_geo, st_drop_geometry(museum_label[,c("ID","nomLabel")]), by="ID", all.x=TRUE)Affichage du tableau de données après ‘traitement’
6.2 Représentation d’une trajectoire : réalisation de la frise chronologique
Pour construire la frise chronologique, la bibliothèque de référence
est ggplot2.
6.2.1 Graphique de base
Les variables utilisées pour l’axe des abscisses (x), des ordonnées (y) et la couleur des individus (musées) sont définies comme suit :
- X = ‘dated’ (date d’arrivée dans le musée) ;
- y = ‘nomLabel.x’ (nom du musée) ;
- color = ‘ADM0_A3’ (couleur en fonction du pays d’appartenance).
Définition des variables
ggplot(data_geo, aes(x = dated, y = nomLabel.x, color = ADM0_A3))
Graphique 3 : Représentation graphique : affichage des labels des
axes
La bibliothèque ggplot2 fonctionne avec une syntaxe
particulière (basée sur la grammaire graphique). Il est possible d’ajouter,
petit à petit, des éléments de mise en forme du graphique.
Ajout de formes géométriques (segments) à représenter sur le graphique
# Construction de 'segments' entre la date d'arrivée (dated) et de départ (datef)
ggplot(data_geo, aes(x = dated, y = nomLabel.x, color = ADM0_A3)) +
geom_segment(aes(xend = datef, yend = nomLabel.x, color = ADM0_A3), size = 6)
Graphique 4 : Représentation graphique : affichage des segments et
de la légende
Assignation du résultat graphique dans un objet
Mon_graph <- ggplot(data_geo, aes(x = dated, y = nomLabel.x, color = ADM0_A3)) +
geom_segment(aes(xend = datef, yend = nomLabel.x, color = ADM0_A3), size = 6)6.2.2 Mise en forme de la représentation d’une trajectoire
La base du graphique a été réalisée. Le travail qui suit procède à sa mise en forme en plusieurs étapes successives :
- ajout des labels avec la fonction
geom_text();
- modification de la palette de couleur avec la fonction
scale_color_manual();
- modification de l’axe des abscisses (intervalle des valeurs et
étiquettes à afficher) ;
- ajout d’un titre et d’un sous-titre ;
- paramétrage de plusieurs éléments du ‘thème’ (repère, légende, axes, couleur de fond…).
Ajout des labels et palette de couleurs
Mon_graph <- Mon_graph +
# Ajout d'une étiquette pour chaque segment représenté
geom_text(aes(label = nomLabel.y, hjust =1.05), size = 3.5, show.legend = FALSE) +
# Modification de la palette de couleur (pays)
scale_color_manual(values = c("#7570b3", "#e7298a", "#66a61e", "#e6ab02", "#a6761d","#1b9e77", "#d95f02"))
# Affichage du résultat
Mon_graph
Graphique 5 : Représentation graphique : affichage des labels au
sein du graphique
Modification de l’axe des abscisses, ajout de titres, paramétrage du ‘thème’
Mon_graph <- Mon_graph +
# Modification de l'axe des abscisse
scale_x_date(date_labels = "%Y", date_breaks = "2 year", minor_breaks = "1 year",
limits = c(as.Date("1994-01-01"),as.Date("2019-01-13")) ) +
# Ajout d'un titre et d'un sous-titre
labs(title = "Le voyage d'un tableau de Johannes Vermeer",
subtitle = "Aux pays des musées, de 2001 à 2019") +
# Paramétrage du 'thème'
theme(panel.grid.major.y = element_blank(),
panel.grid.major.x = element_line(size = 0.2, colour = "#707073"),
panel.grid.minor.x = element_line(size = 0.2, linetype = 3, colour = "#707073"),
panel.border = element_blank(),
panel.background = element_blank(),
axis.text.y = element_blank(),
axis.text.x = element_text(size=8.5, colour = "#FFFFFF"),
axis.title = element_blank(),
rect = element_rect(fill = "#2a2a2b"),
legend.position = c(.93, .27),
legend.key = element_rect(fill = "#2a2a2b"),
legend.key.height = unit(0.1, 'cm'),
legend.background = element_rect(fill = "#2a2a2b"),
legend.margin = margin(0.5,1,1,1),
legend.title = element_blank(),
legend.text = element_text(colour = "#FFFFFF", size = 7),
title = element_text(colour = "#FFFFFF", hjust = 1, vjust = 0),
plot.margin=unit(c(1,1,0.5,1),"cm"))
Mon_graph
Graphique 6 : Représentation graphique : modifications de l’axe des
abscisses, titres et paramétrage du ‘thème’
6.2.3 Représenter une trajectoire : touche finale !
Pour terminer la mise en forme de la frise chronologique, l’image de
l’œuvre analysée et son intitulé sont superposés sur le graphique. Les
bibliothèques jpeg et patchwork permettent
d’importer puis d’insérer l’image du tableau sur la représentation
graphique.
Import de l’image du tableau dans R
# Gestion des images
library(jpeg)
path <- "data/images/Q4660880.jpg"
# Importer une image dans R
img <- readJPEG(path, native = TRUE)Superposition de l’image et de la représentation graphique
# Pour combiner graphiques et images
library(patchwork)
Mon_graph +
# Titre image
annotate("text", x = as.Date("1997-03-01"), y = 7, colour = "#FFFFFF", size = 3.4,
label = "Young Woman Seated\nat a Virginal (1670)") +
# Insertion de l'image du tableau dans la représentation graphique
inset_element(p = img, clip = TRUE, left = 0.04, right = 0.27, top = 0.95, bottom = 0.46)
Graphique 7 : Représentation graphique : superposition de l’image du
tableau à une représentation de sa trajectoire spatio-temporelle
7 Notebook ou document computationnel : à vous de jouer !
La description du processus exploratoire est terminée.
A titre d’expérimentation, pour explorer les données Wikidata, il est
possible de personnaliser le code ci-dessous. Cela permet à
l’utilisateur ou l’utilisatrice d’explorer la répartition spatiale des
œuvres de l’artiste peintre de son choix.
A vous de coder !
Étape 1 : Choisir l’artiste peintre de votre choix et recherchez son identifiant Wikidata. Pour cela, se rendre sur la page Wikidata et dans le champ de recherche, indiquer le nom de l’artiste peintre dont vous souhaitez localiser les œuvres, selon les données non-supervisées fournies par Wikidata.
Veiller à utiliser la saisie semi-automatique pour choisir l’identifiant correspondant à l’entité ‘artiste’ et non à une catégorie ‘Commons’, ou tout autre entité utilisant cette catégorie (par exemple, un bâtiment etc.).
Étape 2 : Copier-coller l’identifiant et le nom de l’artiste peintre choisi-e selon les recommandations ci-dessous.
Le code à modifier se situent à partir de la ligne 977 dans le fichier source du notebook : mon_notebook_final.Rmd.
## Exemple Picasso
# Indiquer l'identifiant de l'artiste choisi-e entre ""
#ID <- "Q5593"
# Indiquer le nom de l'artiste choisi-e entre ""
#NOM <- "Pablo Picasso"
## Exemple Dali
# ID <- "Q5577"
# NOM <- "Salvador Dalí"
## Exemple Nandalal Bose (IN)
ID <- "Q3348980"
NOM <- "Nandalal Bose"
## Exemple Kalervo Palsa (FI)
# ID <- "Q320590"
# NOM <- "Kalervo Palsa"
## Exemple Edvard Munch
# ID <- "Q41406"
# NOM <- "Edvard Munch"
## Exemple Katsushika Hokusai
#ID <- "Q5586"
#NOM <- "Katsushika Hokusai"Étape 3 : Par défaut, les lignes de codes (chunks) utilisées pour cet exercice ne sont pas affichées et ne s’éxécutent pas. Modifier la valeur bouléenne (
FALSEparTRUE) assignée dans l’objet ‘EXO’.
Pour que les blocs de code deviennent actifs et s’exécutent lors de la compilation du R Markdown, modifier la valeur de l’objet ‘EXO’, en lui assignant la valeur TRUE.
Le fait d’assigner la valeur booléenne TRUE à l’objet
‘EXO’ va rendre tous les chunks suivants actifs. Ils seront également
visibles dans le document compilé.
# Jouer l'exemple ?
#EXO <- FALSE
EXO <- TRUEÉtape 4 : Le plus dur est fait ! Il ne reste plus qu’à ‘kniter’ le document et visualiser les résultats.
Fig.9 Cliquez sur ‘Knit’ en haut à gauche de l’éditeur
Une fois le document compilé, l’ensemble du code utilisé pour l’exercice sera affiché ci-dessous, tout comme les représentations graphiques !
7.1 Ma requête SPARQL
Construction de la requête SPARQL personnalisée
# query en fonction de l'ID
query <- paste0("SELECT ?oeuvreLabel ?museeLabel ?coord WHERE { SERVICE wikibase:label { bd:serviceParam wikibase:language '[AUTO_LANGUAGE],en'. } ?oeuvre wdt:P170 wd:", ID, " . OPTIONAL {?oeuvre p:P276 ?loc . ?loc ps:P276 ?musee . ?musee wdt:P625 ?coord} . }")
# Affichage de la requête
print(query)[1] "SELECT ?oeuvreLabel ?museeLabel ?coord WHERE { SERVICE wikibase:label { bd:serviceParam wikibase:language '[AUTO_LANGUAGE],en'. } ?oeuvre wdt:P170 wd:Q3348980 . OPTIONAL {?oeuvre p:P276 ?loc . ?loc ps:P276 ?musee . ?musee wdt:P625 ?coord} . }"
Exécution de la requête
# Requête SPARQL wikidata
my_data <- query_wikidata(query)
# Affichage du résultat
datatable(my_data)7.2 Préparation des données
7.2.1 Nettoyage des données collectées
Suppression des doublons
# Détection/Suppression doublon(s)
my_data <- my_data[!duplicated(my_data$oeuvreLabel), ]Suppression des œuvres sans coordonnées renseignées
# Suppression NA
my_data <- my_data[!is.na(my_data$coord), ]Affichage de la table des données collectées ‘nettoyées’
# Affichage de la table
datatable(my_data)7.2.2 Regroupement par musée
Calcul du nombre d’œuvres par musée
# Regroupement
nb_oeuvre <- aggregate(oeuvreLabel ~ coord + museeLabel, data = my_data, FUN = length)
# Affichage du résultat
datatable(nb_oeuvre)7.2.3 Géoréférencement
Traitement des chaînes de caractères contenant les coordonnées géographiques
# Suppression des chaînes de caractères "Point(" et ")"
nb_oeuvre$coord <- gsub(pattern = 'Point\\(', replacement = '', nb_oeuvre$coord)
nb_oeuvre$coord <- gsub(pattern = '\\)', replacement = '', nb_oeuvre$coord)
# Séparation longitude et latitude en deux colonnes
out <- strsplit(nb_oeuvre$coord, split = ' ')
my_museum <- cbind(nb_oeuvre, do.call(rbind, out))
# Renommage de colonnes créées
colnames(my_museum)[4:5] <- c('long', 'lat')
# Affichage de la table
datatable(my_museum)Géoréférencement (positionnement dans l’espace) des musées
# Géoréférencement
my_museum <- st_as_sf(my_museum, coords = c("long", "lat"), crs = 4326)Modification de la projection cartographique utilisée
# Reprojection de la couche géographique des musées (points)
my_museum <- st_transform(my_museum, crs = st_crs(world))7.2.4 Répartition par pays
Jointure spatiale musée/pays
# Jointure spatiale
my_museum <-st_intersection(my_museum, world[,"ADM0_A3"])Regroupement de lignes et calcul du nombre total d’œuvres par pays
# Regroupement pars pays
by_country <- aggregate(oeuvreLabel ~ ADM0_A3 , data = my_museum, FUN = sum)
# Affichage de la table
datatable(by_country)7.3 Répartition spatiale
7.3.1 Graphique par pays
Graphique de répartition du nombre total d’œuvres par pays
ggplot(data = by_country, aes(x = ADM0_A3, y = oeuvreLabel) ) +
geom_bar(stat="identity") +
ggtitle(paste0("Nombre d'œuvres de ", NOM ,", par pays")) +
xlab("") +
ylab("") +
theme(legend.position = "none",
axis.text.x = element_text(size=8),
axis.text.y = element_text(size=11))7.3.2 Cartographie
7.3.2.1 Exploratoire
mapview(my_museum)7.3.2.2 Thématique
tmap_mode(mode = "view")
tm_shape(my_museum) +
tm_symbols(size="oeuvreLabel",
scale = 2,
col="red3",
border.col="white",
alpha =0.5,
border.lwd=0.1,
border.alpha=0.5,
title.size = "Nb d'œuvres",
id = "museeLabel",
popup.vars=c("Nombre d'œuvres"="oeuvreLabel")) +
tm_layout(panel.labels = paste0("Répartition des peintures de ", NOM ," par musée, selon Wikidata"),
frame = FALSE,
frame.lwd = NA,
inner.margins = c(0, .02, .02, .02))Bibliographie
Annexes
Info session
| setting | value |
|---|---|
| version | R version 4.2.1 (2022-06-23) |
| os | Ubuntu 22.04.1 LTS |
| system | x86_64, linux-gnu |
| ui | X11 |
| language | (EN) |
| collate | fr_FR.UTF-8 |
| ctype | fr_FR.UTF-8 |
| tz | Europe/Paris |
| date | 2022-09-26 |
| pandoc | 2.19.2 @ /usr/lib/rstudio/bin/quarto/bin/tools/ (via rmarkdown) |
| package | ondiskversion | source |
|---|---|---|
| DT | 0.25 | CRAN (R 4.2.1) |
| ggplot2 | 3.3.6 | CRAN (R 4.2.0) |
| jpeg | 0.1.9 | CRAN (R 4.2.1) |
| mapview | 2.11.0 | CRAN (R 4.2.1) |
| patchwork | 1.1.2 | CRAN (R 4.2.1) |
| sf | 1.0.8 | CRAN (R 4.2.1) |
| tmap | 3.3.3 | CRAN (R 4.2.1) |
| WikidataQueryServiceR | 1.0.0 | CRAN (R 4.2.1) |
Citation
KRUMMEICH R, PECOUT H, REY-COYREHOURCQ S (2022). “Histoire de cadre :, élaboration d’une trajectoire spatio-temporelle.” doi:10.48645/xxxxxx, https://doi.org/10.48645/xxxxxx,, https://rzine.fr/publication_rzine/xxxxxxx/.
BibTex :
@Misc{,
title = {Histoire de cadre : élaboration d'une *trajectoire* spatio-temporelle},
subtitle = {Exemple appliqué d'un notebook avec R sur des données Wikidata},
author = {Raphaëlle KRUMMEICH and Hugues PECOUT and Sébastien REY-COYREHOURCQ},
doi = {10.48645/xxxxxx},
url = {https://rzine.fr/publication_rzine/xxxxxxx/},
keywords = {FOS: Other social sciences},
language = {fr},
publisher = {FR2007 CIST},
year = {2022},
copyright = {Creative Commons Attribution Share Alike 4.0 International},
}
Glossaire
une donnée est un objet relationnel, voir par exemple et de manière non-exhaustive, le séminaire 2019 de l’ENSSIB ou encore l’article de Louis Quéré Au juste, qu’est-ce que l’information ?↩︎
une métadonnée est une donnée sur une donnée↩︎
voir par exemple, Construction de typologies de trajectoires, Nicolas Robette, Tuto@Mate#41↩︎
Un environnement de développement intégré, ou IDE pour Integrated Developpment Environment, est un logiciel de création d’applications, qui rassemble des outils de développement fréquemment utilisés dans une seule interface utilisateur graphique (GUI pour Graphical User Interface)↩︎
La bibliothèque des fonctions internes de R est divisée en ensembles de fonctions et de jeux de données apparentés nommés packages (terme que l’équipe de traduction française de R a choisi de conserver tel quel) (Goulet, 2016, p.62)↩︎
pour les différents formats disponibles, voir par exemple la page rmdformats du dépôt Cran-R-project.↩︎
Ce dernier permet de convertir un fichier d’un format donné à un autre (.md vers .html par exemple).↩︎
un préfixe est une modalité de simplification d’écriture faisant référence à un espace de noms, voir notamment, les préfixes wikidata ici↩︎
coordonnées géographiques du système de référence World Geodetic System (WGS84↩︎